﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DictNS
{
  public partial class frmSettings : Form
  {

    #region [Constructors]
    
    public frmSettings()
    {
      InitializeComponent();
      cbSystemProxy.Checked = Convert.ToBoolean(DictUtils.GetAppSetting("useSysProxy").Equals("true", StringComparison.InvariantCultureIgnoreCase));
      tbUserAgent.Text = DictUtils.GetAppSetting("userAgent");
      InitializeProxyTextBoxes();
      InitializeSeachEngineList();
      InitializeOptions();
    }

    public frmSettings(string s) : this()
    {
      if (String.IsNullOrEmpty(s)) { return; }
      tabSettings.SelectedTab = tabSE;
      tabSettings.SelectedTab.Show();
    } 
    #endregion

    #region [Controls Initialization]

    private void InitializeSeachEngineList()
    {
      lvSE.Columns[0].Width = -2; // make wide as possible
      String se = DictUtils.GetAppSetting("se");
      if (String.IsNullOrEmpty(se)) { return; }
      String[] items = DictUtils.GetAppSetting("se").Split('@');
      if (items.Length == 0) { return; }
      lvSE.Items[0].Remove();
      foreach (String s in items) { lvSE.Items.Add(s); }
      String defaultSE = DictUtils.GetAppSetting("defaultSE");
      if (String.IsNullOrEmpty(defaultSE)) {  return;   }
      int idx = Convert.ToInt32(DictUtils.GetAppSetting("defaultSE"));
      MarkSEDefault(idx);
    }

    /// <summary>
    /// Fill text boxes with data gotten from a stored proxy string
    /// </summary>
    private void InitializeProxyTextBoxes()
    {
      String key = "userProxy";
      String str = DictUtils.GetAppSetting(key);
      string[] data = str.Split('|');
      tbProxyAddress.Text = data.Length > 0 ? data[0] : String.Empty;
      tbProxyPort.Text = data.Length > 1 ? data[1] : String.Empty;
      tbUserName.Text = data.Length > 2 ? data[2] : String.Empty;
      tbPass.Text = data.Length > 3 ? data[3] : String.Empty;
      cbProxyType.SelectedItem = data.Length > 3 ? data[4] : String.Empty; ;
      SetProxyCtrlsState();
    }

    /// <summary>
    /// Initialization of Options tab
    /// </summary>
    private void InitializeOptions()
    {
      cbPathHistoryAllowed.Checked = DictUtils.GetAppSetting(cbPathHistoryAllowed.Name, "true").Equals("true");
      nudNumPaths.Text = DictUtils.GetAppSetting(nudNumPaths.Name, "9");
      nudNumPaths.Enabled = cbPathHistoryAllowed.Checked;
    }
    #endregion

    #region [Button related methods]

    private void btnOK_Click(object sender, EventArgs e)
    {
      if(!String.IsNullOrEmpty(tbSE.Text))
      {
        btnAddSE.PerformClick();
        DialogResult = DialogResult.OK;
      }
      DictUtils.SetAppSetting("useSysProxy", (cbSystemProxy.Checked ? "true" : "false"));
      DictUtils.SetAppSetting("userAgent", tbUserAgent.Text);
      DictUtils.SetAppSetting("userProxy", GetNewProxyString());
      SaveSearchEngineList();
      DictUtils.SaveSettings();
    }

    /// <summary>
    /// Clears user defined proxy data
    /// </summary>
    private void btnClear_Click(object sender, EventArgs e)
    {
      tbProxyAddress.Text = String.Empty;
      tbProxyPort.Text = String.Empty;
      tbUserName.Text = String.Empty;
      tbPass.Text = String.Empty;
      DictUtils.SetAppSetting("userProxy", String.Empty);
    }

    /// <summary>
    /// Add new search engine
    /// </summary>
    private void btnAddSE_Click(object sender, EventArgs e)
    {
      if (String.IsNullOrEmpty(tbSE.Text)) { return; }
      lvSE.BeginUpdate();
      if (lvSE.Items[0].Text.Equals("No items in the list", StringComparison.InvariantCultureIgnoreCase)) { lvSE.Items[0].Remove(); }
      lvSE.Items.Add(tbSE.Text);
      if (lvSE.Items.Count == 1) { MarkSEDefault(lvSE.Items.Count -1); }
      lvSE.EndUpdate();
      tbSE.Text = String.Empty;
    }

    #endregion

    #region [CheckBox related methods]

    /// <summary>
    /// Disable controls for user settings
    /// </summary>
    private void cbSystemProxy_CheckedChanged(object sender, EventArgs e)
    {
      Control[] controls = new Control[] { tbProxyAddress, tbProxyPort, tbUserName, tbPass, cbShowPass };
      CheckBox cb = sender as CheckBox;
      foreach (Control c in controls)  {  c.Enabled = !cb.Checked;  }
    }

    /// <summary>
    /// Show / Hide password as a simple text
    /// </summary>
    private void cbShowPass_CheckedChanged(object sender, EventArgs e)
    {
      tbPass.UseSystemPasswordChar = !(sender as CheckBox).Checked;
    }

    private void cbSystemProxy_Click(object sender, EventArgs e) { SetProxyCtrlsState(); }
    
    /// <summary>
    /// Allow / Deny history storage
    /// </summary>
    void AllowHistoryClick(object sender, EventArgs e)
    {
      CheckBox cb = sender as CheckBox;
      DictUtils.SetAppSetting(cb.Name, (cb.Checked ? "true": "false"));
      switch (cb.Name) {
        case "cbPathHistoryAllowed":
          nudNumPaths.Enabled = cb.Checked;
          break;
//        case "cbWordHistoryAllowed":
//          nudNumWords.Enabled = cb.Checked;
//          break;
      }
    }
    
    #endregion

    #region [TextBox related methods]
    /// <summary>
    /// allow only numbers, tab, CR, BS. Pax port allowed is 65535
    /// </summary>
    private void tbProxyPort_KeyPress(object sender, KeyPressEventArgs e)
    {
      TextBox tb = (sender as TextBox);
      tb.Text = Regex.Replace(tb.Text, @"\D", String.Empty);
      String val = String.Format("{0}{1}", tb.Text,  (char.IsDigit(e.KeyChar) ? e.KeyChar.ToString() : String.Empty));
      if (!String.IsNullOrEmpty(val) && Convert.ToInt32(val) > 65535)
      {
        e.Handled = true;
      }
      e.KeyChar = Regex.IsMatch(e.KeyChar.ToString(), @"[\d\t\b\n\r]", RegexOptions.IgnoreCase) ? e.KeyChar : '\0';
//      if (!char.IsDigit(e.KeyChar)) { e.Handled = true; }
    }

    /// <summary>
    /// Enable / Disable Add button
    /// </summary>
    private void tbSE_TextChanged(object sender, EventArgs e)
    {
      btnAddSE.Enabled = !String.IsNullOrEmpty((sender as TextBox).Text);
    }

    #endregion

    #region [NumericUpDown]
    
    void MaxMemVal(object sender, EventArgs e)
    {
      NumericUpDown nud = sender as NumericUpDown;
      DictUtils.SetAppSetting(nud.Name, nud.Text);
    }
    #endregion
    
    #region [Helper methods]

    private void SaveSearchEngineList()
    {
      if (lvSE.Items.Count == 1 && lvSE.Items[0].Text.Equals("No items in the list", StringComparison.InvariantCultureIgnoreCase))
      {
        DictUtils.SetAppSetting("se", String.Empty);
        return;
      }
      int defaultSE = 0;
      List<String> items = new List<string>();
      foreach (ListViewItem i in lvSE.Items)
      {
        items.Add(i.Text);
        if (i.BackColor == Color.LightGray) { defaultSE = i.Index; }
      }
      String s = String.Join("@", items.ToArray<String>());
      if (String.IsNullOrEmpty(s)) { return; }
      DictUtils.SetAppSetting("se", s);
      DictUtils.SetAppSetting("defaultSE", defaultSE.ToString());
    }

    /// <summary>
    /// Enable / Disable user proxy controls depending on the state of System Procy check box
    /// </summary>
    private void SetProxyCtrlsState()
    {
      Control[] ctrls = new Control[] { cbProxyType, tbProxyAddress, tbProxyPort, tbUserName, tbPass, cbShowPass, btnClear };
      foreach (Control c in ctrls) { c.Enabled = !cbSystemProxy.Checked; }
    }

    /// <summary>
    /// Stransform user settings into a string for convinient storage
    /// </summary>
    /// <returns>Composit string with the settings</returns>
    private string GetNewProxyString()
    {
      return String.Format("{0}|{1}|{2}|{3}|{4}", tbProxyAddress.Text, tbProxyPort.Text, tbUserName.Text, tbPass.Text, cbProxyType.SelectedItem);
    }

    #endregion

    #region [Others]
    
    private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
    {
      System.Diagnostics.Process.Start("http://www.useragentstring.com/pages/Browserlist/");
    }

    /// <summary>
    /// If key pressed is Delete key, selected row will be deleted.
    /// </summary>
    private void lvSE_KeyDown(object sender, KeyEventArgs e)
    {
      if (!e.KeyCode.Equals(Keys.Delete))
      {
        e.Handled = true;
        return;
      }
      ListView lv = sender as ListView;
      lv.BeginUpdate();
      foreach (ListViewItem i in lv.SelectedItems) { i.Remove(); }
      if (lv.Items.Count == 0)
      {
        lv.Items.Add("No items in the list");
        lv.Items[0].ForeColor = Color.Gray;
      }
      lv.EndUpdate();
    }

    /// <summary>
    /// mark new search engine as default
    /// </summary>
    /// <param name="idx">index of the clicked row</param>
    private void MarkSEDefault(int idx)
    {
      for (int x = 0; x < lvSE.Items.Count; x++)  {  lvSE.Items[x].BackColor = x == idx ? Color.LightGray : Color.White;  }
    }

    /// <summary>
    /// Double click on a row changes default search engine
    /// </summary>
    private void lvSE_MouseDoubleClick(object sender, MouseEventArgs e)
    {
      ListView lv = sender as ListView;
      lv.BeginUpdate();
      int idx = lv.SelectedIndices[0];
      MarkSEDefault(idx);
      lv.SelectedIndices.Clear();
      lv.EndUpdate();
    }
    
    void FrmSettings_Shown(object sender, EventArgs e)
    {
      switch (tabSettings.SelectedIndex) {
        case 0:
          if(tbProxyAddress.CanFocus)  {  tbProxyAddress.Focus();  }
          break;
        case 1:
          if(tbSE.CanFocus)  {  tbSE.Focus();  }
        	break;
      }
    }

    #endregion

  }
}
